package com.ymt.bpm.util.dingtalk;

import com.alibaba.fastjson.JSONObject;
import com.dingtalk.open.client.ServiceFactory;
import com.dingtalk.open.client.api.model.corp.JsapiTicket;
import com.dingtalk.open.client.api.service.corp.CorpConnectionService;
import com.dingtalk.open.client.api.service.corp.JsapiService;
import com.ymt.bpm.appboot.env.DingtalkProperties;
import com.ymt.bpm.model.PTenantDdMapp;
import com.ymt.bpm.util.dingtalk.aes.DingTalkJsApiSingnature;

import java.net.URLDecoder;

/**
 * AccessToken和jsticket的获取封装
 */
public class AuthHelper {

    /*
     * 在此方法中，为了避免频繁获取access_token，
     * 在距离上一次获取access_token时间在两个小时之内的情况，
     * 将直接从持久化存储中读取access_token
     *
     * 因为access_token和jsapi_ticket的过期时间都是7200秒
     * 所以在获取access_token的同时也去获取了jsapi_ticket
     * 注：jsapi_ticket是在前端页面JSAPI做权限验证配置的时候需要使用的
     * 具体信息请查看开发者文档--权限验证配置
     */
    public static String getAccessToken(PTenantDdMapp mapp, DingtalkProperties prop) throws OApiException {
        String accToken = null;
        try {
            ServiceFactory serviceFactory = ServiceFactory.getInstance();
            CorpConnectionService corpConnectionService = serviceFactory.getOpenService(CorpConnectionService.class);
            accToken = corpConnectionService.getCorpToken(mapp.getCorpId(), mapp.getCorpSecret());
        } catch (Exception e) {
            e.printStackTrace();
            throw new OApiException(-1, "failed to get accessToken", e);
        }
        return accToken;
    }

    /**
     * 获取JSTicket, 用于js的签名计算
     * 正常的情况下，jsapi_ticket的有效期为7200秒，所以开发者需要在某个地方设计一个定时器，定期去更新jsapi_ticket
     */
    public static String getJsapiTicket(PTenantDdMapp mapp, String accessToken) throws OApiException {
        String jsTicket = null;
        try {
            ServiceFactory serviceFactory = ServiceFactory.getInstance();
            JsapiService jsapiService = serviceFactory.getOpenService(JsapiService.class);
            JsapiTicket JsapiTicket = jsapiService.getJsapiTicket(accessToken, "jsapi");
            jsTicket = JsapiTicket.getTicket();
        } catch (Exception e) {
            e.printStackTrace();
            throw new OApiException(-1, "failed to get jsTicket", e);
        }
        return jsTicket;
    }


    public static String sign(String ticket, String nonceStr, long timeStamp, String url) throws OApiException {
        try {
            return DingTalkJsApiSingnature.getJsApiSingnature(url, nonceStr, timeStamp, ticket);
        } catch (Exception e) {
            throw new OApiException(0, "failed to sign url, "+ e.getMessage(), e);
        }
    }

    public static String getSsoToken(PTenantDdMapp mapp, DingtalkProperties prop) throws OApiException {
        String url = prop.getUrlOpenApi() + prop.getPathSsoTokenGet() + "?corpid=" + mapp.getCorpId() + "&corpsecret=" + mapp.getSsoSecret();
        JSONObject response = HttpHelper.httpGet(url);
        String ssoToken;
        if (response.containsKey("access_token")) {
            ssoToken = response.getString("access_token");
        } else {
            throw new OApiException("Sso_token");
        }
        return ssoToken;
    }

}
